Database Trigger
contents
1. 데이터베이스 트리거란?
트리거(Trigger) 는 데이터베이스 서버에서 특정 이벤트가 발생할 때 자동으로 실행되는 특수한 형태의 스토어드 프로시저입니다. 일반적인 프로시저와 달리 사용자가 수동으로 호출(CALL)할 수 없으며, 데이터베이스가 알아서 실행합니다.
- 발동 이벤트:
- DML (데이터 변경):
INSERT,UPDATE,DELETE. - DDL (구조 변경):
CREATE,ALTER,DROP.
- DML (데이터 변경):
- 타이밍:
BEFORE: 데이터가 실제로 쓰이기 전에 실행 (유효성 검사에 적합).AFTER: 데이터가 쓰인 직후에 실행 (로깅/감사에 적합).
2. 일반적인 사용 사례 (좋은 점)
A. 감사 추적 (Audit Trails/Logging)
Users 테이블의 정보가 변경될 때, 변경 전 값을 Users_History 테이블에 저장하고 싶을 때 사용합니다.
- 트리거:
AFTER UPDATE ON Users - 동작:
OLD.email,OLD.phone등을 히스토리 테이블로 복사.
B. 복잡한 유효성 검사
직원의 급여가 매니저의 급여보다 높을 수 없도록 강제하고 싶을 때.
- 트리거:
BEFORE INSERT ON Employees - 동작: 매니저 급여 확인. 만약
NEW.salary > Manager.salary라면 에러를 발생시켜 입력을 차단.
C. 자동 계산
OrderDetails에 상품이 추가되면, 자동으로 Orders 테이블의 total_price를 업데이트.
3. 왜 트리거가 "위험"한가? (나쁜 점)
많은 데이터베이스 아키텍트들이 운영 환경(Production)에서의 트리거 사용을 금지합니다. 이유는 다음과 같습니다.
A. 보이지 않는 로직 ("마법"의 문제)
가장 큰 문제입니다.
- 상황: 개발자가
INSERT INTO Users가 왜 자꾸 실패하는지 디버깅 중입니다. - 조사: API 코드를 봅니다. 정상입니다. 테이블 제약조건을 봅니다. 정상입니다.
- 진실: 3년 전에 퇴사한 개발자가 만들어둔 숨겨진 트리거가 에러를 내고 있었습니다.
- 결론: 트리거는 비즈니스 로직을 DB 깊숙이 숨겨버려서 디버깅을 악몽으로 만듭니다.
B. 연쇄 반응 (Cascading Triggers)
- 트리거 A가 테이블 B를 업데이트합니다.
- 테이블 B의 업데이트가 트리거 B를 발동시킵니다.
- 트리거 B가 테이블 C를 업데이트합니다.
- 트리거 C가 다시 테이블 A를 건드립니다...
- 결과: 무한 루프에 빠지거나 성능이 끔찍하게 저하됩니다.
C. 조용한 성능 살인마
- 대량 업데이트를 실행합니다:
UPDATE Products SET price = price * 1.1(1,000개 행). - 개발자는 한 번의 쿼리라고 생각합니다.
- 현실: 트리거가 있다면, 트리거 함수가 1,000번 실행됩니다 (행마다 한 번씩). 1초 걸릴 쿼리가 10초가 걸리게 됩니다.
D. 벤더 종속성
스토어드 프로시저와 마찬가지로 문법이 독자적입니다. Oracle에서 Postgres로 이전하려면 모든 트리거를 다시 짜야 합니다.
references